/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "core/shader_built_in_functions.h"
#include "core/动画/curve.h"

#include "../Mesh.h"
#include "../面.h"

#include "引擎数据类型.h"
#include "core/mesh_container.h"

#include <matXX.h>
#include <随机数.h>
#include <字符串/str_分割.h>



static S_多边形元素* f_多边形桥接边(S_多边形* poly,
	                       const uvec2* edgeA_ptr, 
                           const uvec2* edgeB_ptr,
	                       uint32 数量max,
	                       uint32 数量min
) {
	vec3* vert = poly->m_顶点.data();

	
	S_多边形元素* 多边形面索引 = (S_多边形元素*)f_core_array_new(0, sizeof(S_面*));
	

	//std::vector<uint32> 以配对遮罩(数量min);
	//--数量max;
	//--数量min;
	
	float32 步进0 = 0;
	float32 步进1 = 0;

	for (uint32 i = 0; i < 数量max; ++i) {
		步进0 += vec_len(vert[edgeA_ptr[i].y] - vert[edgeA_ptr[i].x]);
	}
	for (uint32 i = 0; i < 数量min; ++i) {
		步进1 += vec_len(vert[edgeB_ptr[i].y] - vert[edgeB_ptr[i].x]);
	}
	//以配对遮罩.push_back(edgeB_ptr[数量min-1].y);


	float32 长度比例 = 步进1 / 步进0;
	//if (步进0 >= 步进1) {
	//	长度比例 = 步进1 / 步进0;
	//}
	//else {
	//	长度比例 = 步进0 / 步进1;
	//}
	步进0 = 0;
	步进1 = 0;

	uint32 对边顶点索引 = 0;
	uint32 跨行 = 0;
	for (uint32 i = 0; i < 数量max; ++i) {
		S_面* 多边形面 = new S_面;
		多边形面->polygon = (S_结构对象指针)poly;
		多边形面->材质槽 = 0;

		uvec2 new_edgeA;
		uvec2 new_edgeB;
		
		S_边* 边 = new S_边;
		
		new_edgeA.x = edgeA_ptr[i].x;
		new_edgeA.y = edgeB_ptr[对边顶点索引].x;

		new_edgeB.x = edgeA_ptr[i].y;
		new_edgeB.y = edgeB_ptr[对边顶点索引].y;

		

		多边形面->vertIndex.push_back(edgeA_ptr[i].x);
		多边形面->vertIndex.push_back(edgeA_ptr[i].y);
		


		步进0 += vec_len(vert[edgeA_ptr[i].y] - vert[edgeA_ptr[i].x]);
		assert(对边顶点索引 < 数量min);
		if (步进1 < 步进0 * 长度比例) {

			步进1 += vec_len(vert[edgeB_ptr[对边顶点索引].y] - vert[edgeB_ptr[对边顶点索引].x]);

			边->edge.push_back(new_edgeA);
			边->edge.push_back(new_edgeB);

			多边形面->vertIndex.push_back(edgeB_ptr[对边顶点索引].y);
			多边形面->vertIndex.push_back(edgeB_ptr[对边顶点索引].x);

			if(对边顶点索引+1 < 数量min) ++对边顶点索引;
			++跨行;
		}
		else {
			if (跨行 >= 数量min) {
				边->edge.push_back(new_edgeB);

				new_edgeB = { edgeB_ptr[对边顶点索引].y , new_edgeA.x };
				边->edge.push_back(new_edgeB);
				多边形面->vertIndex.push_back(edgeB_ptr[对边顶点索引].y);
				//多边形面->vertIndex.push_back(new_edgeA.x);
			}
			else {
				多边形面->vertIndex.push_back(edgeB_ptr[对边顶点索引].x);
				//多边形面->vertIndex.push_back(new_edgeA.x);
			}
			if (对边顶点索引 < 数量min) {
				
			}
			
		}

		

		多边形面->edge.push_back(poly->m_边.size());
		poly->m_边.push_back(边);
		

		f_core_array_push_back((S_Array*)多边形面索引, (uint8*)&多边形面);
		//多边形面索引->面索引.push_back(poly->m_面.size());
		多边形面->ID = poly->m_面.size();
		poly->m_面.push_back(多边形面);
	}

	for (auto& e : poly->m_面自定义属性) {
		f_core_array_resize(e.second, poly->m_面.size());
	}
	return 多边形面索引;

}



static void f_多边形桥接点(const vec3* 多数边顶点, const vec3* 少数边顶点, uint32 数量max, uint32 数量min, S_UI32Array* indexs, S_uVec2Array* loop) {
	uint32 index = 0;
	uvec2 环 = {};


	uint32 对边顶点索引 = 0;
	uint32 跨行 = 数量max;
	--数量max;
	--数量min;
	//uint32 num = numA - 1;
	float32 步进0 = 0;
	float32 步进1 = 0;

	for (uint32 i = 0; i < 数量max; ++i) {
		步进0 += vec_len(多数边顶点[i] - 多数边顶点[i + 1]);
	}
	for (uint32 i = 0; i < 数量min; ++i) {
		步进1 += vec_len(少数边顶点[i] - 少数边顶点[i + 1]);
	}


	float32 长度比例 = 步进1 / 步进0;
	步进0 = 0;
	步进1 = 0;
	for (uint32 i = 0; i < 数量max; ++i) {

		index = i;
		f_core_array_push_back((S_Array*)indexs, (uint8*)&index);
		++index;
		f_core_array_push_back((S_Array*)indexs, (uint8*)&index);

		assert(对边顶点索引 <= 数量min);
		步进0 += vec_len(多数边顶点[i + 1] - 多数边顶点[i]);
		

		if (步进1 < 步进0 * 长度比例 && 对边顶点索引 < 数量min) {
			float32 l = vec_len(少数边顶点[对边顶点索引 + 1] - 少数边顶点[对边顶点索引]);
			步进1 += l;

			++对边顶点索引;
			index = 跨行 + 对边顶点索引;
			f_core_array_push_back((S_Array*)indexs, (uint8*)&index);

			--index;
			f_core_array_push_back((S_Array*)indexs, (uint8*)&index);

			环.y = 4;
		}
		else {
			index = 跨行 + 对边顶点索引;
			f_core_array_push_back((S_Array*)indexs, (uint8*)&index);

			环.y = 3;
		}
		
		loop->ptr_userData[i] = 环;
		环.x += 环.y;
	}

}




S_多边形* f_surface_创建多边形() {
	S_多边形* 多边形 = new S_多边形;
	多边形->m_元素组 = (S_多边形元素Array*)f_core_array_new(0, sizeof(S_多边形元素*), false);
	return 多边形;
}

void f_surface_清除多边形元素(S_多边形* 多边形) {
//#pragma omp parallel sections
//	{
//#pragma omp section
//		{
			uint32 num = 多边形->m_边.size();
			auto* edge = 多边形->m_边.data();
			for (int32 i = 0; i < num; ++i) {
				delete edge[i];
			}
//		}
//#pragma omp section
//		{
			num = 多边形->m_面.size();
			auto* face = 多边形->m_面.data();
			for (int32 i = 0; i < num; ++i) {
				delete face[i];
			}
//		}
//	}
	
	f_core_array_resize((S_Array*)多边形->m_元素组, 0);


	多边形->m_UV索引.clear();
	多边形->m_顶点.clear();
	多边形->m_法线.clear();
	多边形->m_UV.clear();
	
	多边形->m_边.clear();
	多边形->m_面.clear();

	多边形->m_UV层数量 = 0;

	for (auto& e : 多边形->m_点自定义属性) {
		f_core_array_free(e.second);
	}
	for (auto& e : 多边形->m_面自定义属性) {
		f_core_array_free(e.second);
	}

	多边形->m_点自定义属性.clear();
	多边形->m_面自定义属性.clear();
}

void f_surface_销毁多边形(S_多边形* 多边形) {
	f_surface_清除多边形元素(多边形);
	f_core_array_free((S_Array*)多边形->m_元素组);
	delete 多边形;
}

S_多边形元素* f_surface_多边形桥接(S_多边形* poly, const S_边& edgeA, const S_边& edgeB) {
	uint32 numA = edgeA.edge.size();
	uint32 numB = edgeB.edge.size();
	if (!numA || !numB) return nullptr;

	S_多边形元素* 面索引 = nullptr;

	vec3* vert = poly->m_顶点.data();
	auto* edgeA_ptr = edgeA.edge.data();
	auto* edgeB_ptr = edgeB.edge.data();

	/*vec3 全局方向A = {};
	for (uint32 i = 0; i < numA; ++i) {
		vec_add(&全局方向A, vert[edgeA_ptr[i].y] - vert[edgeA_ptr[i].x]);
	}
	vec3 全局方向B = {};
	for (uint32 i = 0; i < numB; ++i) {
		vec_add(&全局方向B, vert[edgeB_ptr[i].y] - vert[edgeB_ptr[i].x]);
	}
	vec_normalize(&全局方向A);
	vec_normalize(&全局方向B);


	
	if (vec_dot(全局方向A, 全局方向B) >= 0) {
		面索引 = f_多边形桥接边(poly, edgeA_ptr, edgeB_ptr, numA, numB);
	}
	else {
		面索引 = f_多边形桥接边(poly, edgeA_ptr, edgeB_ptr, numA, numB);
	}*/

	uint32 数量max = DEF_Max(numA, numB);
	uint32 数量min = DEF_Min(numA, numB);
	//--numA;
	//--numB;

	if (numA >= numB) {
		面索引 = f_多边形桥接边(poly, edgeA_ptr, edgeB_ptr, numA, numB);
	}
	else {
		面索引 = f_多边形桥接边(poly, edgeB_ptr, edgeA_ptr, numB, numA);
	}

	f_core_array_push_back((S_Array*)poly->m_元素组, (uint8*)&面索引);
	return 面索引;
}

S_Vec3Array* f_surface_点桥接(const S_Vec3Array* a, const S_Vec3Array* b, S_UI32Array* indexs, S_uVec2Array* loop) {
	uint32 numA = a->count;
	uint32 numB = b->count;

	S_Vec3Array* vert = (S_Vec3Array*)f_core_array_new(0, sizeof(vec3));
	if (!numA || !numB) return vert;

	uint32 数量max = DEF_Max(numA, numB);
	uint32 数量min = DEF_Min(numA, numB);
	--numA;
	--numB;
	

	/*vec3 全局方向A = {};
	for (uint32 i = 0; i < numA; ++i) {
		vec_add(&全局方向A, a->ptr_userData[i+1] - a->ptr_userData[i]);
	}
	vec3 全局方向B = {};
	for (uint32 i = 0; i < numB; ++i) {
		vec_add(&全局方向B, b->ptr_userData[i + 1] - b->ptr_userData[i]);
	}
	vec_normalize(&全局方向A);
	vec_normalize(&全局方向B);

	
	if (vec_dot(全局方向A, 全局方向B) >= 0) {
		
	}
	else {
		
	}*/
	

	const vec3* 多数边;
	const vec3* 少数边;
	if (numA >= numB) {
		多数边 = a->ptr_userData;
		少数边 = b->ptr_userData;

		f_core_array_append((S_Array*)vert, (S_Array*)a);
		f_core_array_append((S_Array*)vert, (S_Array*)b);
	}
	else {
		多数边 = b->ptr_userData;
		少数边 = a->ptr_userData;

		f_core_array_append((S_Array*)vert, (S_Array*)b);
		f_core_array_append((S_Array*)vert, (S_Array*)a);
	}

	f_core_array_resize((S_Array*)loop, 数量max - 1);
	f_core_array_resize((S_Array*)indexs, 0);
	f_多边形桥接点(多数边, 少数边, 数量max, 数量min, indexs, loop);

	
	return vert;
}



static Inline float32 f_面角度大小(const vec3* vert, const uvec3& index, const vec3& 法线) {
	vec3 左边 = vert[index.x];
	vec3 中间 = vert[index.y];
	vec3 右边 = vert[index.z];

	vec3 v1 = vec_normalize(右边 - 中间);
	vec3 v2 = vec_normalize(中间 - 左边);
	
	return vec_dot(v1, v2) + 1.0;
	float32 dt = vec_dot(vec_cross(v1, v2), 法线);
	if (dt >= 0) {
		dt = vec_dot(v1, v2) + 1.0;
		return dt;
	}
	return -1;
}

static int32 f_分割出一个三角形(const vec3* vert, const vec3& 面法线, uint32* index, uint32 num, uvec3* 当前三角形顶点) {
	float32 d = 0;
	int32 当前选中顶点 = -1;
	for (uint32 i = 0; i < num; ++i) {
		uvec3 三角形;
		三角形.x = i;
		三角形.y = i + 1;
		三角形.z = i + 2;

		if (三角形.y >= num) {
			三角形.y = 三角形.y - num;
		}
		if (三角形.z >= num) {
			三角形.z = 三角形.z - num;
		}
		int32 id = 三角形.y;
		

		uvec3 临时三角形索引;
		临时三角形索引.x = index[三角形.x];
		临时三角形索引.y = index[三角形.y];
		临时三角形索引.z = index[三角形.z];


		float32 dt = f_面角度大小(vert, 临时三角形索引, 面法线);
		if (dt > d) {
			d = dt;
			当前三角形顶点[0] = 临时三角形索引;
			当前三角形顶点[1] = 三角形;

			当前选中顶点 = id;
		}
	}

	return 当前选中顶点;
}

void f_surface_多边形三角化(S_Mesh* mesh, const S_多边形* 多边形) {
	std::vector<uvec3> 三角形索引;
	std::vector<uvec3> 纹理坐标索引[8];

	std::map<std::wstring, S_Array*> 面自定义属性;
	for (auto& e : 多边形->m_面自定义属性) {
		面自定义属性[e.first] = f_core_array_new_type(0, f_core_array_getType(e.second));
	}


	uint32 num = 多边形->m_面.size();
	auto* face = 多边形->m_面.data();
	auto* vert = 多边形->m_顶点.data();
	auto* uvIndex = 多边形->m_UV索引.data();


	uint32 UV索引物体级偏移 = f_surface_fill层纹理坐标(mesh, 多边形->m_UV);
	f_core_array_reserve((S_Array*)mesh->m_材质槽ID, 0);
	//mesh->m_材质槽ID.resize(num*2);
	//auto* 材质槽指针 = mesh->m_材质槽ID.data();

	for (uint32 i = 0; i < num; ++i) {
		auto tmpIndex = face[i]->vertIndex;
		auto tmpUvLoop = face[i]->uvLoopIndex;

		uint32 uvNum = tmpUvLoop.size();
		uint32 面顶点数量 = tmpIndex.size();
		if(面顶点数量 < 3) continue;

		auto face_ptr = tmpIndex.data();


		std::vector<uint32> tmpUVIndex[8];
		vec3 dir0;

		#pragma omp parallel sections
		{
			#pragma omp section
			{
				//计算中点
				vec3 中点{};
				for (uint32 j = 0; j < 面顶点数量; ++j) {
					中点 += vert[face_ptr[j]];
				}
				中点 /= num;
		
				dir0 = vec_normalize(中点 - vert[face_ptr[0]]);
				vec3 dir1 = vec_normalize(vert[face_ptr[1]] - 中点);
				dir0 = vec_normalize(vec_cross(dir0, dir1));
			}
			#pragma omp section
			{
				
				for (uint32 j = 0; j < uvNum; ++j) {
					uvec2 UV全局索引偏移 = tmpUvLoop[j];
					for (uint32 k = 0; k < UV全局索引偏移.y; ++k) {
						tmpUVIndex[j].push_back(uvIndex[UV全局索引偏移.x + k]);
					}
				}
			}
		}

		


		uint32 分解面顶点数量 = tmpIndex.size();
		for (uint32 j = 0; j < 分解面顶点数量; ) {
			face_ptr = tmpIndex.data();
			//auto* UVLoop_ptr = tmpUvLoop.data();
			
			uvec3 分割纹理坐标索引{};

			if (分解面顶点数量 <= 3) {
				//材质槽指针[三角形索引.size()] = face[i]->材质槽;
				三角形索引.push_back({ face_ptr[0], face_ptr[1], face_ptr[2] });
				f_core_array_push_back((S_Array*)mesh->m_材质槽ID, (uint8*)&face[i]->材质槽);
				

				//if (uvNum >= face_num) 纹理坐标索引.push_back({ uv_ptr[0], uv_ptr[1], uv_ptr[2] });
				if (uvNum) {
					auto* uv_ptr = tmpUvLoop.data();
					for (uint32 uv层 = 0; uv层 < uvNum; ++uv层) {
						uint32 num = tmpUVIndex[uv层].size();
						if (num) {
							分割纹理坐标索引.x = tmpUVIndex[uv层][0];
							分割纹理坐标索引.y = tmpUVIndex[uv层][1 < num ? 1 : 0];
							分割纹理坐标索引.z = tmpUVIndex[uv层][2 < num ? 2 : 0];
						}
						纹理坐标索引[uv层].push_back(分割纹理坐标索引);
					}
				}
				else {
					纹理坐标索引[0].push_back(分割纹理坐标索引);
				}


				//自定义属性
				for (auto& e : 多边形->m_面自定义属性) {
					f_core_array_push_back(面自定义属性[e.first], f_core_array_at(e.second, i));
				}

				break;
			}

			//顶点和UV索引
			uvec3 当前三角形顶点局部偏移[2];
			int32 当前选中顶点 = f_分割出一个三角形(vert, dir0, face_ptr, 分解面顶点数量, 当前三角形顶点局部偏移);

			if (当前选中顶点 >= 0) {
				//材质槽指针[三角形索引.size()] = face[i]->材质槽;
				
				#pragma omp parallel sections
				{
					#pragma omp section
					{
						if (uvNum) {
							//auto* uv_ptr = tmpUvLoop.data();
							for (uint32 uv层 = 0; uv层 < uvNum; ++uv层) {
								uint32 num = tmpUVIndex[uv层].size();
								if (num) {
									分割纹理坐标索引.x = tmpUVIndex[uv层][当前三角形顶点局部偏移[1].x < num ? 当前三角形顶点局部偏移[1].x : 0];
									分割纹理坐标索引.y = tmpUVIndex[uv层][当前三角形顶点局部偏移[1].y < num ? 当前三角形顶点局部偏移[1].y : 0];
									分割纹理坐标索引.z = tmpUVIndex[uv层][当前三角形顶点局部偏移[1].z < num ? 当前三角形顶点局部偏移[1].z : 0];
									
									if (当前选中顶点 < num) {
										tmpUVIndex[uv层].erase(tmpUVIndex[uv层].begin() + 当前选中顶点);
									}
								}
								纹理坐标索引[uv层].push_back(分割纹理坐标索引);
							}
						}
						else {
							纹理坐标索引[0].push_back(分割纹理坐标索引);
						}
					}
					#pragma omp section
					{
						三角形索引.push_back(当前三角形顶点局部偏移[0]);
						f_core_array_push_back((S_Array*)mesh->m_材质槽ID, (uint8*)&face[i]->材质槽);

						//自定义属性
						for (auto& e : 多边形->m_面自定义属性) {
							f_core_array_push_back(面自定义属性[e.first], f_core_array_at(e.second, i));
							//vec3 a = *(vec3*)f_core_array_at(e.second, i);
							//std::cout<<a.x<<std::endl;
						}

						//移除选中顶点索引
						tmpIndex.erase(tmpIndex.begin() + 当前选中顶点);
						分解面顶点数量 = tmpIndex.size();
						j = 0;
					}
				}
			}
			else {
				++j;
			}
		}
	}
	
	

	//mesh->m_材质槽ID.resize(三角形索引.size());
	if (三角形索引.size()) {
		mesh->f_填充索引数据(sizeof(uvec3), 三角形索引.size(), (void*)三角形索引.data());
	}
	else {
		mesh->f_Clear();
		mesh->f_Clear索引();
	}
	

	f_surface_fill纹理坐标索引(mesh, 纹理坐标索引);
	


	for (auto& e : 面自定义属性) {
		mesh->m_面自定义属性区间偏移[e.first] = f_surface_填充自定义属性(mesh, e.second, 1);
	}
	//(*mesh->m_自定义属性);
}



void f_surface_合并顶点(S_多边形* 多边形, float32 最大距离) {
	std::vector<S_VecSphere> 包围盒;
	f_surface_计算三角形球体包围盒(多边形, 包围盒);


}



void f_surface_计算平滑法线(S_多边形* 多边形) {
	std::vector<S_VecSphere> 包围盒;
	f_surface_计算三角形球体包围盒(多边形, 包围盒);

}

void f_surface_计算三角形球体包围盒(S_多边形* 多边形, std::vector<S_VecSphere>& 包围盒) {
	auto 顶点 = 多边形->m_顶点.data();
	auto 索引 = 多边形->m_面.data();

	uint32 num = 多边形->m_面.size();
	包围盒.resize(num);
	auto* 球 = 包围盒.data();
	
#pragma omp parallel for
	for (int32 i = 0; i < num; ++i) {
		auto face_ptr = 索引[i]->vertIndex.data();
		uint16 face_num = 索引[i]->vertIndex.size();

		//计算中点
		vec3 中点{};
		for (uint32 j = 0; j < face_num; ++j) {
			中点 += 顶点[face_ptr[j]];
		}
		中点 /= num;

		索引[i]->面中心 = 中点;

		int32 maxLenID = 0;
		float32 maxLen = 0;
		for (uint32 j = 0; j < face_num; ++j) {
			float32 len = vec_len(中点 - 顶点[face_ptr[j]]);
			if (len > maxLen) {
				len = maxLen;
				maxLen = j;
			}
		}
		球[i].pos = 中点;
		球[i].radius = maxLen;

	}

}



S_多边形元素* f_surface_边网格化(S_多边形* 多边形, S_边& 边, S_边& 倒角) {
	uint32 num = 边.edge.size();
	--num;

	auto* edge_ptr = 边.edge.data();
	for (uint32 i = 0; i < num; ++i) {

	}
	//S_多边形面* face = f_surface_多边形桥接(多边形, 倒角, 倒角);

	return nullptr;
}

float32 f_surface_边长度(S_边& 边, vec3* vert) {
	uint32 num = 边.edge.size();
	auto edge_pr = 边.edge.data();
	float32 len = 0;
	for (uint32 i = 0; i < num; ++i) {
		len += vec_len(vert[edge_pr[i].y] - vert[edge_pr[i].x]);
	}
	return len;
}

void f_surface_边多点采样(S_边* 边,
	                 const vec2& 区间, 
					 float32 偏移,

	                float32 最小间隔,
	                float32 随机间隔,
	                float32 随机种子,
	                
	                
	                S_Vec3Array* 采样返回坐标, 
	                S_Vec3Array* 采样返回向量
	) {

	if(!边 || !边->polygon) return;
	S_多边形* 多边形 = (S_多边形*)边->polygon;

	uint32 num = 边->edge.size();
	auto edge_ptr = 边->edge.data();
	vec3* vert_ptr = 多边形->m_顶点.data();

	float32 len = f_surface_边长度(*边, vert_ptr);

	float32 步进 = 0;
	
	vec2 步进区间;
	步进区间.x = 区间.x * len;
	步进区间.y = 区间.y * len;

	f_core_array_clear((S_Array*)采样返回坐标);
	f_core_array_clear((S_Array*)采样返回向量);


	最小间隔 = DEF_Max(最小间隔, 0);
	随机间隔 = DEF_Max(随机间隔, 0);
	float32 当前步进 = 偏移;
	for (uint32 i = 0; i < num; ++i) {
		vec3 线向量 = vert_ptr[edge_ptr[i].y] - vert_ptr[edge_ptr[i].x];
		float32 当前线段长度 = vec_normalize(&线向量);
		

		if (当前线段长度 > 0) {
			while (当前步进 < 当前线段长度) {
				vec3 采样坐标 = 线向量 * 当前步进 + vert_ptr[edge_ptr[i].x];

				float32 当前全局步进 = 步进 + 当前步进;
				if (当前全局步进 >= 步进区间.x && 当前全局步进 <= 步进区间.y) {
					f_core_array_push_back((S_Array*)采样返回坐标, (uint8*)&采样坐标);
					f_core_array_push_back((S_Array*)采样返回向量, (uint8*)&线向量);
				}
				
				随机种子 += i+1;
				当前步进 += (f_random_F32(随机种子) * 随机间隔);
				当前步进 += (最小间隔);

				if (当前步进 > 当前线段长度 || 当前步进 > 10000) // || 当前步进 <= INFINITE
					break;
			}
		}
		
		当前步进 -= 当前线段长度;
		//处理多余步进部分
		步进 += 当前线段长度;

		当前步进 = DEF_Max(当前步进, 0);
		
	}

	vec3 末尾坐标 = vert_ptr[edge_ptr[num-1].y];
	vec3 末尾向量 = vec_normalize(末尾坐标 - vert_ptr[edge_ptr[num - 1].x]);

	f_core_array_push_back((S_Array*)采样返回坐标, (uint8*)&末尾坐标);
	f_core_array_push_back((S_Array*)采样返回向量, (uint8*)&末尾向量);
}

void f_surface_边采样(S_边* 边, const vec2& 区间, float32 偏移, vec3& 采样返回坐标, vec3& 采样返回向量) {

	if (!边 || !边->polygon) return;
	S_多边形* 多边形 = (S_多边形*)边->polygon;

	uint32 num = 边->edge.size();
	auto edge_ptr = 边->edge.data();
	vec3* vert_ptr = 多边形->m_顶点.data();

	float32 len = f_surface_边长度(*边, vert_ptr);
	if(偏移 < 区间.x) {
		采样返回坐标 = num ? vert_ptr[edge_ptr[0].x] : vec3{};
		
		采样返回向量 = {};
		return;
	}
	if (偏移 > 区间.y) {
		采样返回坐标 = num ? vert_ptr[edge_ptr[num-1].y] : vec3{};
		
		采样返回向量 = {};
		return;
	}


	偏移 *= len;

	float32 步进 = 0;
	//float32 当前步进 = 偏移;
	for (uint32 i = 0; i < num; ++i) {
		vec3 线向量 = vert_ptr[edge_ptr[i].y] - vert_ptr[edge_ptr[i].x];
		float32 当前线段长度 = vec_normalize(&线向量);

		if (步进 + 当前线段长度 >= 偏移) {
			当前线段长度 = 步进 + 当前线段长度 - 偏移;

			采样返回坐标 = vert_ptr[edge_ptr[i].y] - 线向量 * 当前线段长度;
			采样返回向量 = 线向量;
			break;
		}

		步进 += 当前线段长度;
	}

}

S_多边形元素* f_surface_复制(S_多边形* poly, S_多边形元素* 要复制的面元素, const vec3& loc, const vec3& rot, const vec3& scal, uint8 合并元素) {
	
	auto 新建面数量 = 要复制的面元素->count;
	if(!新建面数量) return nullptr;


	auto 已有面数量 = poly->m_面.size();
	const auto* faceIndex_ptr = 要复制的面元素->ptr_userData;

	const auto* face_ptr = poly->m_面.data();
	const auto* vert_ptr = poly->m_顶点.data();
	const auto* normal_ptr = poly->m_法线.data();

	uint32 当前顶点数量 = poly->m_顶点.size();
	//uint32 当前顶点索引数量 = self->m_顶点索引.size();


	std::vector<uint32> 新顶点索引;
	std::vector<vec3> 新顶点;
	std::vector<vec3> 新法线;
	std::vector<vec2> 新UV;
	
	std::vector<S_边*> 新边;
	//std::vector<S_面*> 新面;

	
	auto mat = f_mat44_构建XYZ变换矩阵({loc, rot, scal});
	auto rotMat = f_mat44_构建XYZ变换矩阵({{}, rot, {1,1,1}});
	
	S_多边形元素* 元素 = (S_多边形元素*)f_core_array_new(0, sizeof(S_面*));
	//switch (合并元素) {
	//	case 0: 元素 = (S_多边形元素*)f_core_array_new(0, sizeof(S_面*)); break;
	//	case 1: 元素 = (S_多边形元素*)f_core_array_from((S_Array*)要复制的面元素); break;
	//}

	//uvec2 点属性拷贝区间 = { 已有面数量 };
	//uvec2 面属性拷贝区间 = {};

	S_Array* 顶点拷贝索引 = (S_Array*)f_core_array_new_type(0, E_值类型::e_Type_UI32_1D);
	S_Array* 面点拷贝索引 = (S_Array*)f_core_array_new_type(0, E_值类型::e_Type_UI32_1D);

	for (uint32 i = 0; i < 新建面数量; ++i) {
		S_面* 多边形面 = new S_面;
		多边形面->polygon = (S_结构对象指针)poly;

		auto* index = faceIndex_ptr[i]->vertIndex.data();
		auto indexNum = faceIndex_ptr[i]->vertIndex.size();

		
		for (uint32 j = 0; j < indexNum; ++j) {
			多边形面->vertIndex.push_back(新顶点.size() + 当前顶点数量);
			
			新顶点.push_back(mat * vert_ptr[index[j]]);
			新法线.push_back(rotMat * normal_ptr[index[j]]);

			f_core_array_push_back((S_Array*)poly->m_元素组, (uint8*)&元素);

			f_core_array_push_back(顶点拷贝索引, (uint8*)&index[j]);
		}

		多边形面->uvLoopIndex = faceIndex_ptr[i]->uvLoopIndex;
		多边形面->edge = faceIndex_ptr[i]->edge;
		多边形面->材质槽 = faceIndex_ptr[i]->材质槽;
		多边形面->ID = poly->m_面.size();

		f_core_array_push_back(面点拷贝索引, (uint8*)&多边形面->ID);


		f_core_array_push_back((S_Array*)元素, (uint8*)&多边形面);
		poly->m_面.emplace_back(多边形面);
	}

	poly->m_顶点.insert(poly->m_顶点.end(), 新顶点.begin(), 新顶点.end());
	poly->m_法线.insert(poly->m_法线.end(), 新法线.begin(), 新法线.end());
	//self->m_UV.insert(self->m_UV.end(), 新UV.begin(), 新UV.end());
	//poly->m_面.insert(poly->m_面.end(), 新面.begin(), 新面.end());
	f_core_array_push_back((S_Array*)poly->m_元素组, (uint8*)&元素);


	for (auto& e : poly->m_点自定义属性) {
		f_core_array_resize(e.second, poly->m_顶点.size());

		f_core_array_区间自拷贝(e.second, (S_UI32Array*)顶点拷贝索引, 当前顶点数量);
	}
	for (auto& e : poly->m_面自定义属性) {
		f_core_array_resize(e.second, poly->m_面.size());

		f_core_array_区间自拷贝(e.second, (S_UI32Array*)面点拷贝索引, 已有面数量);
	}


	return 元素;
}

void f_surface_多边形元素变换(S_多边形元素* 面元素, const vec3& loc, const vec3& rot, const vec3& scal) {
	auto num = 面元素->count;
	auto* faceIndex_ptr = 面元素->ptr_userData;

	S_多边形* 多边形 = (S_多边形*)faceIndex_ptr[0]->polygon;
	auto* vert = 多边形->m_顶点.data();
	auto* normal = 多边形->m_法线.data();

	auto mat_loc = f_mat44_构建XYZ变换矩阵({ loc, rot, scal });
	auto mat_rot = f_mat44_构建XYZ变换矩阵({ {}, rot, scal});
	for (uint32 i = 0; i < num; ++i) {
		//auto* face_ptr = self->m_面.data();
		auto* index = faceIndex_ptr[i]->vertIndex.data();
		uint32 pointNum = faceIndex_ptr[i]->vertIndex.size();

		for (uint32 j = 0; j < pointNum; ++j) {
			vert[index[j]] = mat_loc * vert[index[j]];
			normal[index[j]] = mat_rot * normal[index[j]];
		}
	}
}

void f_surface_多边形元素组变换(S_多边形元素Array* 面元素, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal) {
	auto num = 面元素->count;

	bool 移动多例 = loc->count >= num;
	bool 旋转多例 = rot->count >= num;
	bool 缩放多例 = scal->count >= num;

	for (uint32 i = 0; i < num; ++i) {
		vec3& l = 移动多例 ? loc->ptr_userData[i] : loc->ptr_userData[0];
		vec3& r = 旋转多例 ? rot->ptr_userData[i] : rot->ptr_userData[0];
		vec3& s = 缩放多例 ? scal->ptr_userData[i] : scal->ptr_userData[0];

		if (面元素->ptr_userData[i]) {
			f_surface_多边形元素变换(面元素->ptr_userData[i], l, r, s);
		}
	}
}

void f_surface_多边形变换(S_多边形* self, const vec3& loc, const vec3& rot, const vec3& scal) {
	auto num = self->m_顶点.size();

	auto* point = self->m_顶点.data();
	auto* normal = self->m_法线.data();


	auto mat_loc = f_mat44_构建XYZ变换矩阵({ loc, rot, scal });
	auto mat_rot = f_mat44_构建XYZ变换矩阵({ {}, rot, scal});

	for (uint32 i = 0; i < num; ++i) {
		point[i] = mat_loc * point[i];
		normal[i] = mat_rot * normal[i];
	}
}

S_多边形Array* f_surface_复制多边形(S_多边形* 源, const vec3& loc, const vec3& rot, const vec3& scal) {
	return nullptr;
}

S_多边形Array* f_surface_拷贝多边形(const S_多边形Array* 源, S_多边形Array* 目标, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal) {
	uint32 num = 目标->count;
	S_多边形Array* ploy = (S_多边形Array*)f_core_array_new(num, sizeof(S_多边形*));

	bool 多源 = 源->count >= num;
	bool 移动多例 = loc->count >= num;
	bool 旋转多例 = loc->count >= num;
	bool 缩放多例 = loc->count >= num;

	
	//auto mat = f_mat44_构建XYZ变换矩阵({loc, rot, scal});
	for (uint32 i = 0; i < num; ++i) {
		//auto 目标多边形 = 目标->ptr_userData[i];
		
		S_多边形* 源多边形;
		if (多源) {
			源多边形 = 源->ptr_userData[i];
		}
		else {
			源多边形 = 源->ptr_userData[0];
		}

		if (!源多边形 || !目标->ptr_userData[i]) continue;

		vec3 移动;
		if(移动多例) 移动 = loc->ptr_userData[i];
		else 移动 = loc->ptr_userData[0];
		vec3 旋转;
		if (旋转多例) 旋转 = rot->ptr_userData[i];
		else 旋转 = rot->ptr_userData[0];
		vec3 缩放;
		if (缩放多例) 缩放 = scal->ptr_userData[i];
		else 缩放 = scal->ptr_userData[0];

		f_surface_copy(源多边形, 目标->ptr_userData[i]);

		f_surface_多边形变换(目标->ptr_userData[i], 移动, 旋转, 缩放);

		ploy->ptr_userData[i] = 目标->ptr_userData[i];
	}

	return ploy;
}

//void f_surface_释放元素(S_多边形* self, S_多边形元素* 面元素) {
//	delete 面元素;
//}

void f_surface_释放元素组(S_多边形* self, S_多边形元素Array* 面元素) {
	for (uint32 i = 0; i < 面元素->count; ++i) {
		delete 面元素->ptr_userData[i];
	}
	f_core_array_free((S_Array*)面元素);
}

S_多边形元素Array* f_surface_线实体化(S_边Array* 边, S_Vec3Array* 倒角, S_F32Array* 半径, const S_曲线& curve, int32 节点类型, int32 半径迭代方式) {
	S_多边形元素Array* 元素组 = (S_多边形元素Array*)f_core_array_new(0, sizeof(S_多边形元素*));

	switch (节点类型) {
		case 0:{
			S_Vec3Array* newVert = (S_Vec3Array*)f_core_array_new(0, sizeof(vec3));

			for (uint32 i = 0; i < 边->count; ++i) {
				if(!边->ptr_userData[i]) continue;
				int32 段数量 = 边->ptr_userData[i]->edge.size() - 1;
				if(段数量 < 0) continue;


				S_多边形* 多边形 = (S_多边形*)边->ptr_userData[i]->polygon;
				auto* vert = 多边形->m_顶点.data();
				auto* 点索引 = 边->ptr_userData[i]->edge.data();


				
				std::vector<vec4> q; q.reserve(段数量 + 2);
				std::vector<vec3> v; v.reserve(段数量 + 2);
				std::vector<float32> 长度步进;

				float32 总长度 = 0;
				for (uint32 k = 0; k <= 段数量; ++k) {
					auto L = 点索引[k];
					vec3 v1 = (vert[L.y] - vert[L.x]);
					总长度 += vec_len(v1);

					长度步进.push_back(总长度);
				}
				长度步进.push_back(总长度);


				q.push_back(f_graph_quat两向量(normalize(vert[点索引[0].y] - vert[点索引[0].x]), { 0, 1, 0 }));
				v.push_back(vert[点索引[0].x]);
				for (uint32 k = 0; k < 段数量; ++k) {
					auto L = 点索引[k];
					auto R = 点索引[k+1];

					vec3 v1 = normalize(vert[L.y] - vert[L.x]);
					vec3 v2 = normalize(vert[R.y] - vert[R.x]);
					//vec3 中点 = (v2 - v1) * 0.5;
					vec3 法线 = vec_cross(v1, v2);
					vec3 旋转朝向 = vec_cross(法线, v2 + v1);


					//q.push_back(f_graph_quat两向量((v2 - v1), { 0, 1, 0 }));
					q.push_back(f_graph_quat两向量(normalize(v1 + v2) , { 0, 1, 0 }));
					v.push_back(vert[L.y]);
				}
				q.push_back(f_graph_quat两向量((vert[点索引[段数量].y] - vert[点索引[段数量].x]), { 0, 1, 0 }));
				v.push_back(vert[点索引[段数量].y]);


				
				++段数量;
				std::vector<S_边*> 新边; 新边.reserve(段数量 + 2);
				float32 s = 0;
				for (uint32 k = 0; k <= 段数量; s = 长度步进[k] / 总长度, ++k) {
					f_core_array_copy((S_Array*)newVert, (S_Array*)倒角);

					s = f_graph_钳制曲线采样(s, curve, {0,1});
					for (uint32 d = 0; d < newVert->count; ++d) {
						newVert->ptr_userData[d] = (f_graph_quat反向变换坐标(q[k], 倒角->ptr_userData[d] * s) + v[k]);
						//newVert->ptr_userData[d] = f_graph_quatTranform(q[k], newVert->ptr_userData[d]) + v[k];
					}
					uvec2 vr = f_surface_添加多边形顶点(多边形, newVert, {});
					auto* 边 = f_surface_添加多边形边(多边形, vr, 1);
					if(边) 新边.push_back(边);

				}
				
				段数量 = int32(新边.size()) - 1;
				for (int32 k = 0; k < 段数量; ++k) {
					S_多边形元素* e = f_surface_多边形桥接(多边形, *新边[k], *新边[k+1]);
					f_core_array_push_back((S_Array*)元素组, (uint8*)&e);
				}
				
			}

			f_core_array_free((S_Array*)newVert);
			break;
		}
		case 1: {
			break;
		}
		default:
			break;
	}

	return 元素组;
}

//void f_surface_销毁多边形元素(S_多边形元素* 面组) {
//	delete 面组;
//}



uvec2 f_surface_添加多边形顶点(S_多边形* self, S_Vec3Array* verts, S_Vec3Array* normal) {
	if(!self) return {};

	auto& m_多边形 = *(self);

	uvec2 r;
	r.x = m_多边形.m_顶点.size();
	r.y = verts->count;

	if (m_多边形.m_顶点.size() > 50000000)
		return {};

	m_多边形.m_顶点.resize(r.x + r.y);
	auto* 顶点坐标 = m_多边形.m_顶点.data();

	for (auto& e : m_多边形.m_点自定义属性) {
		f_core_array_resize(e.second, r.x + r.y);
	}

	for (uint32 i = 0; i < r.y; ++i) {
		顶点坐标[i + r.x] = verts->ptr_userData[i];
	}


	//r.x = self->m_法线.size();
	//r.y = normal->count;
	self->m_法线.resize(r.x + r.y);
	/*auto* 法线 = self->m_法线.data();
	for (uint32 i = 0; i < r.y; ++i) {
		法线[i + r.x] = verts->ptr_userData[i];
	}*/

	return r;
}

uvec2 f_surface_添加多边形法线(S_多边形* 多边形, S_Vec3Array* verts) {
	uvec2 r;
	r.x = 多边形->m_法线.size();
	r.y = verts->count;

	多边形->m_法线.resize(r.x + r.y);
	auto* 法线 = 多边形->m_法线.data();

	for (uint32 i = 0; i < r.y; ++i) {
		法线[i + r.x] = verts->ptr_userData[i];
	}

	return r;
}

uvec2 f_surface_添加多边形纹理坐标(S_多边形* 多边形, const S_Vec2Array* uv, const S_UI32Array* indexs, S_uVec2Array* 环) {
	//uvec2 r;
	uint32 已有UV顶点偏移 = 多边形->m_UV.size();
	uint32 新UV数量 = uv->count;
	//r.y = verts->count;
	

	多边形->m_UV.resize(已有UV顶点偏移 + 新UV数量);
	auto* UV坐标 = 多边形->m_UV.data();

	
	for (uint32 i = 0; i < 新UV数量; ++i) {
		UV坐标[i + 已有UV顶点偏移] = uv->ptr_userData[i];
	}



	uint32 新索引数量 = indexs->count;
	uint32 UV索引偏移 = 多边形->m_UV索引.size();

	if (新索引数量 < 1) {
		新索引数量 = indexs->count;

		UV索引偏移 = 多边形->m_UV索引.size();
		多边形->m_UV索引.resize(UV索引偏移 + 新索引数量);
		auto* UV索引 = 多边形->m_UV索引.data();

		for (uint32 i = 0; i < 新索引数量; ++i) {
			UV索引[i + UV索引偏移] = DEF_Min(indexs->ptr_userData[i], 新UV数量) + 已有UV顶点偏移;
		}


		新索引数量 += UV索引偏移;
		for (uint32 i = 0; i < 环->count; ++i) {
			环->ptr_userData[i].x = DEF_Min(环->ptr_userData[i].x + UV索引偏移, 新索引数量 - 1);
			环->ptr_userData[i].y = 新索引数量;
		}
	}
	else {
		新索引数量 = 新UV数量;

		UV索引偏移 = 多边形->m_UV索引.size();
		多边形->m_UV索引.resize(UV索引偏移 + 新索引数量);
		auto* UV索引 = 多边形->m_UV索引.data();

		for (uint32 i = 0; i < 新索引数量; ++i) {
			UV索引[i + UV索引偏移] = i + 已有UV顶点偏移;
		}



		新索引数量 += UV索引偏移;
		for (uint32 i = 0; i < 环->count; ++i) {
			环->ptr_userData[i].x = DEF_Min(环->ptr_userData[i].x + UV索引偏移, 新索引数量 - 1);
			环->ptr_userData[i].y = 新索引数量;
		}
	}
	

	

	return { 已有UV顶点偏移, 新UV数量 };
}

void f_surface_设置边形顶点法线(S_多边形* 多边形, S_Vec3Array* verts, uint32 offset) {
	多边形->m_法线;
}

S_边* f_surface_添加多边形边(S_多边形* self, uvec2 offset, int32 线模式) {
	if (offset.y < 2 || offset.x > 100000000) return nullptr;

	auto& m_多边形 = *(self);

	S_边* edge = new S_边;
	edge->polygon = (S_结构对象指针)self;

	switch (线模式)
	{
	case 0: {
		uint32 num = offset.y - 1;
		for (uint32 i = 0; i < num; ++i) {
			uvec2 e;
			e.x = offset.x + i;
			e.y = offset.x + i + 1;
			edge->edge.push_back(e);
		}
		break;
	}
	case 1: {
		uint32 num = offset.y - 1;
		for (uint32 i = 0; i < num; ++i) {
			uvec2 e;
			e.x = offset.x + i;
			e.y = offset.x + i + 1;
			edge->edge.push_back(e);
		}

		uvec2 e;
		e.x = offset.x + num;
		e.y = offset.x;
		edge->edge.push_back(e);
		
		break;
	}
	case 2: {
		uint32 num = offset.y / 2;
		for (uint32 i = 0; i < num; ++i) {
			uvec2 e;
			e.x = i * 2;
			e.y = i * 2 + 1;
			edge->edge.push_back(e + offset.x);
		}
		break;
	}
	}
	
	m_多边形.m_边.push_back(edge);
	return edge;
}

S_面* f_surface_添加多边形面(S_多边形* poly, uint32* index, uint32 num, uint32 offset) {
	S_面* 多边形面 = new S_面;
	S_边* edge = new S_边;

	多边形面->polygon = (S_结构对象指针)poly;


	多边形面->vertIndex.resize(num);
	for (uint32 i = 0; i < num; ++i) {
		多边形面->vertIndex[i] = index[i] + offset;
		多边形面->材质槽 = 0;

		uvec2 vert_range;
		if (i + 1 >= num) {
			vert_range = { index[num-1], index[0] };
		}
		else {
			vert_range = { index[i], index[i + 1] };
		}
		vert_range += offset;
		edge->edge.push_back(vert_range);
		
	}
	多边形面->ID = poly->m_面.size();

	poly->m_边.push_back(edge);
	poly->m_面.push_back(多边形面);

	for (auto& e : poly->m_面自定义属性) {
		f_core_array_resize(e.second, poly->m_面.size());
	}
	return 多边形面;
}

S_多边形元素* f_surface_添加多边形元素(S_多边形* poly, S_Vec3Array* 顶点, S_UI32Array* 索引, S_uVec2Array* 环) {
	uint32 面数量 = 环->count;
	if (!面数量 && 索引->count) {
		面数量 = 1;
	}

	S_多边形元素* 多边形元素 = (S_多边形元素*)f_core_array_new(0, sizeof(S_面*));

	uint32 索引数量 = 索引->count;
	uint32 新顶点数量 = 顶点->count;
	uint32 顶点开始偏移 = poly->m_顶点.size();
	uint32 边开始偏移 = poly->m_边.size();
	poly->m_顶点.resize(顶点开始偏移 + 顶点->count);
	auto* vert = poly->m_顶点.data();
	for (uint32 i = 0; i < 新顶点数量; ++i) {
		vert[i + 顶点开始偏移] = 顶点->ptr_userData[i];
	}

	uint32 面开始偏移 = poly->m_面.size();
	poly->m_面.resize(面开始偏移 + 面数量);


	新顶点数量 = poly->m_顶点.size();
	顶点开始偏移;
	if (环->count) {
		for (uint32 i = 0; i < 面数量; ++i) {
			uvec2 r = 环->ptr_userData[i];
			r.y = DEF_Min(r.y, 索引数量);
			r.x = DEF_Min(r.x, 索引数量);


			S_面* 多边形面 = new S_面;
			多边形面->polygon = (S_结构对象指针)poly;

			多边形面->vertIndex.resize(r.y);
			
			for (uint32 j = 0; j < r.y; ++j) {
				uint32 index = DEF_Min(索引->ptr_userData[r.x + j] + 顶点开始偏移, 新顶点数量);
				多边形面->vertIndex[j] = index;
			}
			//多边形元素->面索引.push_back(面开始偏移 + i);
			f_core_array_push_back((S_Array*)多边形元素, (uint8*)&多边形面);
			poly->m_面[面开始偏移 + i] = 多边形面;



			S_边* 边 = new S_边;
			if (r.y) {
				--(r.y);
				边->edge.resize(r.y);
				for (uint32 j = 0; j < r.y; ++j) {
					uvec2 r = { 多边形面->vertIndex[j], 多边形面->vertIndex[j + 1] };
					边->edge[j] = r;
				}
				边->edge[r.y] = { 多边形面->vertIndex[r.y], 多边形面->vertIndex[0] };
			}
			


			多边形面->edge.push_back(poly->m_边.size());
			poly->m_边.push_back(边);

		}
	}
	else {
		//多边形元素->面索引.push_back(面开始偏移);
		S_面* 多边形面 = new S_面;
		多边形面->polygon = (S_结构对象指针)poly;

		for (uint32 i = 0; i < 索引数量; ++i) {
			多边形面->vertIndex[i] = DEF_Min(索引->ptr_userData[i] + 顶点开始偏移, 新顶点数量);
		}
		poly->m_面[面开始偏移] = 多边形面;
		f_core_array_push_back((S_Array*)多边形元素, (uint8*)&多边形面);
	}
	
	f_core_array_push_back((S_Array*)poly->m_元素组, (uint8*)&多边形元素);

	for (auto& e : poly->m_面自定义属性) {
		f_core_array_resize(e.second, poly->m_面.size());
	}
	return 多边形元素;
}

S_多边形元素* f_surface_从区间索引构建多边形面(S_多边形* poly, uvec2 index, uvec2 UV环, uint32 uv层, bool 面朝向) {
	S_面* 面 = new S_面;
	S_多边形元素* 多边形元素 = (S_多边形元素*)f_core_array_new(0, sizeof(S_面*));

	uint32 num = index.y;
	if (num) {
		uint32 IndexOffset = 面->vertIndex.size();

		面->vertIndex.resize(IndexOffset + num);
		if (面朝向) {
			for (uint32 i = 0; i < num; ++i) {
				面->vertIndex[i + IndexOffset] = index.x + i;
			}
		}
		else {
			uint32 offset = num + index.x - 1;
			for (int32 i = 0; i < num; ++i) {
				面->vertIndex[IndexOffset + i] = offset - i;
			}
		}



		if (uv层 >= 面->uvLoopIndex.size()) {
			面->uvLoopIndex.push_back({});
			uv层 = 面->uvLoopIndex.size() - 1;
		}
		面->uvLoopIndex[uv层] = UV环;


		面->ID = poly->m_面.size();
		//多边形元素->面索引.push_back(poly->m_面.size());
		f_core_array_push_back((S_Array*)多边形元素, (uint8*)&面);
		poly->m_面.push_back(面);

		for (auto& e : poly->m_面自定义属性) {
			f_core_array_resize(e.second, poly->m_面.size());
		}
	}
	
	f_core_array_push_back((S_Array*)poly->m_元素组, (uint8*)&多边形元素);
	return 多边形元素;
}

void f_surface_从索引构纹理面坐标(S_多边形* self, S_UI32Array* faceIndex, S_1DArray* uvIndex) {
	//self->m_面[faceIndex]->uvIndex;
}

void f_surface_取面索引(S_多边形* self, S_多边形元素* 面元素, S_1DArray* 索引) {
	uint32 old_num = 索引->count;
	if (!面元素 || !self) {
		for (uint32 i = 0; i < old_num; ++i) {
			free(索引->ptr_userData[i]);
		}
		return;
	}

	
	//uint32 num = 面元素->面索引.size();
	uint32 num = 面元素->count;
	for (uint32 i = num; i < old_num; ++i) {
		free(索引->ptr_userData[i]);
	}

	f_core_array_resize((S_Array*)索引, num);
	for (uint32 i = old_num; i < num; ++i) {
		索引->ptr_userData[i] = (S_Array*)malloc(sizeof(S_Array));
	}


	//auto* faceIndex_ptr = 面元素->面索引.data();
	auto* faceIndex_ptr = 面元素->ptr_userData;
	for (uint32 i = 0; i < num; ++i) {
		auto* face = faceIndex_ptr[i];

		索引->ptr_userData[i]->ptr_userData = (uint8*)face->vertIndex.data();
		索引->ptr_userData[i]->count = face->vertIndex.size();
	}
}

void f_surface_取面顶点(const S_面* 面元素, S_Vec3Array* 顶点) {
	if(!面元素->polygon) return;
	auto p = *((S_多边形*)(面元素->polygon));
	uint32 num = 面元素->vertIndex.size();
	f_core_array_resize((S_Array*)顶点, num);

	auto* index_ptr = 面元素->vertIndex.data();
	auto* vert_ptr = ((S_多边形*)(面元素->polygon))->m_顶点.data();
	
	for (uint32 i = 0; i < num; ++i) {
		顶点->ptr_userData[i] = vert_ptr[index_ptr[i]];
	}
}

void f_surface_取面法线(const S_面* 面元素, S_Vec3Array* 法线) {
	if (!面元素->polygon) return;

	uint32 num = 面元素->vertIndex.size();
	f_core_array_resize((S_Array*)法线, num);

	auto* index_ptr = 面元素->vertIndex.data();
	auto* vert_ptr = ((S_多边形*)(面元素->polygon))->m_法线.data();

	for (uint32 i = 0; i < num; ++i) {
		法线->ptr_userData[i] = vert_ptr[index_ptr[i]];
	}
}

void f_surface_取面中心(const S_面* 面元素, S_Vec3Array* 中心) {
	if (!面元素->polygon) return;

	uint32 num = 面元素->vertIndex.size();
	f_core_array_resize((S_Array*)中心, 1);

	auto* index_ptr = 面元素->vertIndex.data();
	auto* vert_ptr = ((S_多边形*)(面元素->polygon))->m_顶点.data();

	vec3 重心{};
	for (uint32 i = 0; i < num; ++i) {
		重心 += vert_ptr[index_ptr[i]];
	}

	中心->ptr_userData[0] = 重心 / num;
}

void f_surface_取面顶点法线(const S_面* 面元素, S_Vec3Array* 法线) {
	if (!面元素->polygon) return;

	uint32 num = 面元素->vertIndex.size();
	f_core_array_resize((S_Array*)法线, num);

	auto* index_ptr = 面元素->vertIndex.data();
	auto* vert_ptr = ((S_多边形*)(面元素->polygon))->m_法线.data();

	for (uint32 i = 0; i < num; ++i) {
		法线->ptr_userData[i] = vert_ptr[index_ptr[i]];
	}
}

S_边* f_surface_取多边形边(const S_多边形* self, uint32 ID) {
	uint32 num = self->m_边.size();
	if (ID < num) {
		return self->m_边[ID];
	}
	else if (num) {
		return self->m_边.back();
	}

	static S_多边形 多边形;
	static S_边 边{ (S_结构对象指针)&多边形, {}};
	return &边;
}

void f_surface_取多边形多个元素(S_多边形* self, S_UI32Array* 元素索引, S_多边形元素Array* 元素组) {
	f_core_array_resize((S_Array*)元素组, 0);

	uint32 总元素组数量 = self->m_元素组->count;
	for (uint32 i = 0; i < 元素索引->count; ++i) {
		uint32 index = 元素索引->ptr_userData[i];

		if (index < 总元素组数量) {
			f_core_array_push_back((S_Array*)元素组, (uint8*)&self->m_元素组->ptr_userData[index]);
		}
	}
}

S_多边形元素* f_surface_取多边形元素(S_多边形* self, uint32 元素索引) {
	if (self && 元素索引 < self->m_元素组->count) {
		return self->m_元素组->ptr_userData[元素索引];
	}
	//---------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	static S_多边形元素* 元素 = (S_多边形元素*)f_core_array_new(0, sizeof(S_面*));
	return 元素;
}

S_面* f_surface_取多边形面(S_多边形元素* 面元素, uint32 index) {
	//if (index < 面元素->面索引.size()) {
		//return self->m_面[面元素->面索引[index]];
	//}
	if (index < 面元素->count && 面元素->count) {
		return 面元素->ptr_userData[index];
	}

	static S_面 空;
	return &空;
}

//uint32 f_surface_取多边形元素面数量(S_多边形* self, S_多边形元素* 面元素) {
//	return 面元素->面索引.size();
//}



void f_surface_设置面顶点(const S_面* 面元素, const S_Vec3Array* 顶点) {
	if (!面元素->polygon) return;

	uint32 num = 面元素->vertIndex.size();
	if(顶点->count < num || !num) return;

	auto* index_ptr = 面元素->vertIndex.data();
	auto* vert_ptr = ((S_多边形*)(面元素->polygon))->m_顶点.data();
	for (uint32 i = 0; i < num; ++i) {
		vert_ptr[index_ptr[i]] = 顶点->ptr_userData[i];
	}
}

void f_surface_设置面顶点法线(const S_面* 面元素, const S_Vec3Array* 法线) {
	if (!面元素->polygon) return;

	uint32 num = 面元素->vertIndex.size();
	if (法线->count < num || !num) return;

	auto* index_ptr = 面元素->vertIndex.data();
	auto* normal_ptr = ((S_多边形*)(面元素->polygon))->m_法线.data();
	for (uint32 i = 0; i < num; ++i) {
		normal_ptr[index_ptr[i]] = 法线->ptr_userData[i];
	}
}

void f_surface_设置面法线(const S_面* 面元素, const S_Vec3Array* 法线) {
}

void f_surface_设置面中心(const S_面* 面元素, const S_Vec3Array* 中心) {
}


void f_surface_设置元素UV环(S_多边形* self, S_多边形元素* 元素, S_uVec2Array* 环, uint32 uv层) {
	uint32 面数量 = 元素->count;
	auto* 面索引 = 元素->ptr_userData;

	//auto* face = self->m_面.data();
	bool 环单例 = 环->count < 面数量;

	for (uint32 i = 0; i < 面数量; ++i) {
		//uint32 index = 面索引[i];

		if (uv层 >= 面索引[i]->uvLoopIndex.size()) {
			面索引[i]->uvLoopIndex.resize(DEF_Min(uv层 + 1, 8));
			//面索引[i]->uvLoopIndex.push_back({});
			//uv层 = 面索引[i]->uvLoopIndex.size();

			self->m_UV层数量 = DEF_Max(self->m_UV层数量, uv层);
			//uv层 = self->m_UV层数量 - 1;
		}

		if (环单例) 面索引[i]->uvLoopIndex[uv层] = 环->ptr_userData[0];
		else 面索引[i]->uvLoopIndex[uv层] = 环->ptr_userData[i];
	}
}

void f_surface_设置元素组UV环(S_多边形* self, S_多边形元素Array* 元素组, S_uVec2Array* 环, uint32 uv层) {
	uint32 num = 元素组->count;

	for (uint32 i = 0; i < num; ++i) {
		uint32 num = 元素组->count;
		f_surface_设置元素UV环(self, 元素组->ptr_userData[i], 环, uv层);
	}
}

void f_surface_设置元素材质槽ID(S_多边形* self, const S_多边形元素* 元素, S_UI32Array* 槽ID) {
	//uint32 num = 元素->面索引.size();
	uint32 num = 元素->count;
	auto* faceIndex_ptr = 元素->ptr_userData;

	bool in1单例 = 槽ID->count < num;

	//auto* face_ptr = self->m_面.data();
	for (uint32 i = 0; i < num; ++i) {
		if(in1单例) faceIndex_ptr[i]->材质槽 = 槽ID->ptr_userData[0];
		else faceIndex_ptr[i]->材质槽 = 槽ID->ptr_userData[i];
	}
}

void f_surface_设置元素组材质槽ID(S_多边形* self, const S_多边形元素Array* 元素, S_UI32Array* 槽ID) {
	uint32 num = 元素->count;
	//auto* face_ptr = self->m_面.data();
	
	for (uint32 j = 0; j < 元素->count; ++j) {
		S_多边形元素* 面组 = 元素->ptr_userData[j];

		uint32 num = 面组->count;
		bool in1单例 = 槽ID->count < num;

		auto* faceIndex_ptr = 面组->ptr_userData;
		
		for (uint32 i = 0; i < num; ++i) {
			if (in1单例) faceIndex_ptr[i]->材质槽 = 槽ID->ptr_userData[0];
			else faceIndex_ptr[i]->材质槽 = 槽ID->ptr_userData[i];
		}
	}
}



S_多边形元素* f_surface_构建预设多边形(S_多边形* poly, const uvec3& 细分, const vec3& 大小, uint8 类型) {

	std::vector<vec3> 顶点;
	std::vector<vec3> 法线;
	std::vector<vec2> UV;
	std::vector<uint32> 索引;

	bool 三角化 = false;

	uvec2 球体经纬{};
	switch (类型) {
	case 0:
		f_graph_构建平面(*(vec2*)((float32*)&大小), *(uvec2*)((uint32*)&细分), 顶点, 法线, UV, 索引, false);
		break;
	case 1:
		球体经纬 = f_graph_构建球体(细分.x, 细分.y, 大小.x, 顶点, 法线, UV, 索引, false);
		break;
	case 2:
		f_graph_构建立方体(大小, 细分, 顶点, 法线, UV, 索引, false);
		break;
	default:
		break;
	}

	uint32 index_offset = poly->m_顶点.size();

	
	uint32 num = 索引.size();
	auto index_ptr = 索引.data();

	S_多边形元素* 面组 = (S_多边形元素*)f_core_array_new(0, sizeof(S_面*));
	switch (类型) {
	case 1: {
		uint32 offset = 0;
		for (uint32 x = 0; x < 球体经纬.x; ++x) {
			//面组->面索引.push_back(poly->m_面.size());
			auto face = f_surface_添加多边形面(poly, &index_ptr[offset], 3, poly->m_顶点.size());
			f_core_array_push_back((S_Array*)面组, (uint8*)&face);
			offset += 3;
			
		}
		if (三角化) {
			for (uint32 y = 1; y < 球体经纬.y - 1; ++y) {
				for (uint32 x = 0; x < 球体经纬.x; ++x) {
					//面组->面索引.push_back(poly->m_面.size());
					auto face = f_surface_添加多边形面(poly, &index_ptr[offset], 3, poly->m_顶点.size());
					f_core_array_push_back((S_Array*)面组, (uint8*)&face);
					offset += 4;
				}
			}
		}
		else {
			for (uint32 y = 1; y < 球体经纬.y - 1; ++y) {
				for (uint32 x = 0; x < 球体经纬.x; ++x) {
					//面组->面索引.push_back(poly->m_面.size());
					auto face = f_surface_添加多边形面(poly, &index_ptr[offset], 4, poly->m_顶点.size());
					f_core_array_push_back((S_Array*)面组, (uint8*)&face);
					offset += 4;
				}
			}
		}

		for (uint32 x = 0; x < 球体经纬.x; ++x) {
			//面组->面索引.push_back(poly->m_面.size());
			auto face = f_surface_添加多边形面(poly, &index_ptr[offset], 3, poly->m_顶点.size());
			f_core_array_push_back((S_Array*)面组, (uint8*)&face);
			offset += 3;
			
		}
		
		
		break;
	}
	default: {
		if (三角化) {
			for (uint32 i = 0; i < num; i += 3) {
				//面组->面索引.push_back(poly->m_面.size());
				auto face = f_surface_添加多边形面(poly, &index_ptr[i], 3, poly->m_顶点.size());
				f_core_array_push_back((S_Array*)面组, (uint8*)&face);
			}
		}
		else {
			for (uint32 i = 0; i < num; i += 4) {
				//面组->面索引.push_back(poly->m_面.size());
				auto face = f_surface_添加多边形面(poly, &index_ptr[i], 4, poly->m_顶点.size());
				f_core_array_push_back((S_Array*)面组, (uint8*)&face);
			}
		}
	}
	}
	
	S_Vec3Array vert;
	vert.ptr_userData = 顶点.data();
	vert.count = 顶点.size();

	S_Vec3Array normal;
	normal.ptr_userData = 法线.data();
	normal.count = 法线.size();
	f_surface_添加多边形顶点(poly, &vert, &normal);


	f_core_array_push_back((S_Array*)poly->m_元素组, (uint8*)&面组);

	return 面组;
}

void f_surface_投影纹理坐标(S_多边形* poly, int32 投影类型, S_多边形元素* 面元素, const Mat44f& mat) {
	auto* faceIndex_ptr = 面元素->ptr_userData;
	auto face_num = 面元素->count;

	auto* vert_ptr = poly->m_顶点.data();
	//auto* face_ptr = poly->m_面.data();
	
	vec3 中心 = mat * vec3{};
	switch (投影类型) {
	case 0: {
		for (uint32 i = 0; i < face_num; ++i) {
			auto* face_ptr = faceIndex_ptr[i];
			uint32 vertIndexNum = face_ptr->vertIndex.size();
			uint32* vertIndex_ptr = face_ptr->vertIndex.data();

			auto& uvIndex = face_ptr->uvLoopIndex[0];

			uint32 UV开始偏移 = poly->m_UV.size();
			poly->m_UV索引.reserve(UV开始偏移 + vertIndexNum);

			for (uint32 j = 0; j < vertIndexNum; ++j) {
				poly->m_UV索引.push_back(poly->m_UV.size());

				vec3 v =  vert_ptr[vertIndex_ptr[j]] - 中心;
				poly->m_UV.push_back({ v.x, v.z });
				
			}
			uvIndex = { UV开始偏移, vertIndexNum };
		}
		break;
	}
	case 1: {
		break;
	}
	case 2: {
		break;
	}
	case 3: {
		for (uint32 i = 0; i < face_num; ++i) {
			//uint32 面索引 = faceIndex_ptr[i];
			auto* face_ptr = faceIndex_ptr[i];
			uint32 vertIndexNum = face_ptr->vertIndex.size();
			uint32* vertIndex_ptr = face_ptr->vertIndex.data();

			auto& uvIndex = face_ptr->uvLoopIndex[0];

			uint32 UV开始偏移 = poly->m_UV.size();
			poly->m_UV索引.reserve(UV开始偏移 + vertIndexNum);

			for (uint32 j = 0; j < vertIndexNum; ++j) {
				poly->m_UV索引.push_back(poly->m_UV.size());

				vec3 v =  vert_ptr[vertIndex_ptr[j]] - 中心;
				v = mat * v;
				//f_graph_两向量夹角弧度(v, 方向);
				vec2 uv = f_CylindricalProjectUV(v);
				
				poly->m_UV.push_back({ v.x, v.z });
				//uvIndex.push_back(poly->m_UV.size());
				//poly->m_UV.push_back(uv);
			}
			uvIndex = { UV开始偏移, vertIndexNum };
		}
		break;
	}
	case 4: {
		for (uint32 i = 0; i < face_num; ++i) {
			//uint32 面索引 = faceIndex_ptr[i];
			auto* face_ptr = faceIndex_ptr[i];
			uint32 vertIndexNum = face_ptr->vertIndex.size();
			uint32* vertIndex_ptr = face_ptr->vertIndex.data();

			auto& uvIndex = face_ptr->uvLoopIndex[0];

			uint32 UV开始偏移 = poly->m_UV.size();
			poly->m_UV索引.reserve(UV开始偏移 + vertIndexNum);

			for (uint32 j = 0; j < vertIndexNum; ++j) {
				poly->m_UV索引.push_back(poly->m_UV.size());

				vec3 v =  vert_ptr[vertIndex_ptr[j]] - 中心;
				v = mat * v;
				//f_graph_两向量夹角弧度(v, 方向);
				vec2 uv = f_equirectangularUV(v);
				//uvIndex.push_back(poly->m_UV.size());
				poly->m_UV.push_back(uv);
			}
			uvIndex = { UV开始偏移, vertIndexNum };
		}
		break;
	}
	}
}

void f_surface_多边形转网格(const S_多边形* 多边形, S_Mesh* 面网格, S_Mesh* 点网格, S_Mesh* 边网格, bool 计算平滑法线) {
	uint32 num = 多边形->m_顶点.size();
	std::vector<S_VNT1> 面顶点(num);
	std::vector<S_VC> 顶点边(num);
	auto* vert_ptr = 面顶点.data();


	for (uint32 i = 0; i < num; ++i) {
		顶点边[i].vert = vert_ptr[i].vert = 多边形->m_顶点[i];
		顶点边[i].color = f_PackData4X8({ 127,127,0,255 });

		vert_ptr[i].normal = {};
		vert_ptr[i].UV = {};
	}
	f_surface_fill顶点数据(点网格, 顶点边);


	if (面网格) {
		num = 多边形->m_面.size();
		//auto* face_ptr = 多边形->m_面.data();
		if (num) {
			f_surface_fill顶点数据(面网格, 面顶点);
			f_surface_多边形三角化(面网格, 多边形);

			S_Bounding cube = f_surface_计算包围盒(面网格);
			if (计算平滑法线) {
				std::vector<std::vector<uint32>> 顶点相邻面;
				f_surface_构建顶点相连面索引(面网格, 顶点相邻面);
				f_surface_计算面平滑法线(面网格, 顶点相邻面);
			}
		}
	}
	

	if (边网格) {
		num = 多边形->m_边.size();
		顶点边.clear();
		顶点边.reserve(num*2);
		for (uint32 i = 0; i < num; ++i) {
			uint32 边数量 = 多边形->m_边[i]->edge.size();

			auto edge = 多边形->m_边[i]->edge.data();
			for (uint32 j = 0; j < 边数量; ++j) {
				uint32 id = i * 边数量 + j;

				if (edge[j].x >= num || edge[j].y >= num) {
					//std::cout<<"err: 多边形转网格<<边索引越界>>"<<std::endl;
					continue;
				}

				S_VC v;
				v.vert = 多边形->m_顶点[edge[j].x];
				v.color = f_PackData4X8({ 0,0,0,255 });
				顶点边.push_back(v);

				v.vert = 多边形->m_顶点[edge[j].y];
				v.color = f_PackData4X8({ 0,0,0,255 });
				顶点边.push_back(v);
			}
		}
		f_surface_fill顶点数据(边网格, 顶点边);
	}
}


void f_surface_创建自定义属性(S_多边形* 多边形, S_网格自定义属性* 类型) {
	std::set<std::wstring> key;
	switch (类型->m_分布方式) {
		case 0: {
			for (auto& e : 多边形->m_点自定义属性) {
				key.insert(e.first);
			}
			f_str_数组填充末尾(key, *类型->m_Name);
			

			if (多边形->m_点自定义属性.find(*类型->m_Name) == 多边形->m_点自定义属性.end()) {
				多边形->m_点自定义属性[*类型->m_Name] = f_core_array_new_type(多边形->m_顶点.size(), 类型->m_Type);
			}
			break;
		}
		case 1: {
			for (auto& e : 多边形->m_面自定义属性) {
				key.insert(e.first);
			}
			f_str_数组填充末尾(key, *类型->m_Name);

			if (多边形->m_面自定义属性.find(*类型->m_Name) == 多边形->m_面自定义属性.end()) {
				多边形->m_面自定义属性[*类型->m_Name] = f_core_array_new_type(多边形->m_面.size(), 类型->m_Type);
			}
			break;
		}
	}

	//nameProp->m_UI->m_部件-> = true;
}

void f_surface_设置面自定义属性(S_多边形元素* 多边形元素, S_网格自定义属性* 类型, S_Array* a) {
	S_多边形* 多边形;
	if (多边形元素->count && 多边形元素->ptr_userData[0]) {
		多边形 = (S_多边形*)多边形元素->ptr_userData[0]->polygon;
	}
	else {
		return;
	}

	if((*类型->m_Name).empty()) return;

	switch (类型->m_分布方式) {
		case 0: {
			if (多边形->m_点自定义属性.find(*类型->m_Name) != 多边形->m_点自定义属性.end()) {
				
				auto& e = 多边形->m_点自定义属性[*类型->m_Name];
				if(!e) return;
				//f_core_array_不对等复制(e, a);

				for (uint32 i = 0; i < 多边形元素->count; ++i) {
					auto* indexs = 多边形元素->ptr_userData[i]->vertIndex.data();
					uint32 faceVertNum = 多边形元素->ptr_userData[i]->vertIndex.size();

					bool 多例 = a->count >= faceVertNum;
					for (uint32 k = 0; k < faceVertNum; ++k) {
						f_core_array_元素复制(e, a, indexs[k], 多例 ? k : 0);
					}
				}
			}
			break;
		}
		case 1: {
			if (多边形->m_面自定义属性.find(*类型->m_Name) != 多边形->m_面自定义属性.end()) {
				auto& e = 多边形->m_面自定义属性[*类型->m_Name];
				//f_core_array_不对等复制(e, a);
				
				bool 多例 = a->count >= 多边形元素->count;
				for (uint32 i = 0; i < 多边形元素->count; ++i) {
					多边形元素->ptr_userData[i]->ID;

					f_core_array_元素复制(e, a, 多边形元素->ptr_userData[i]->ID, 多例 ? i : 0);
				}
			}
			break;
		}
	}
}

void f_surface_设置元素自定义属性(S_多边形元素Array* 多边形元素组, S_网格自定义属性* 类型, S_Array* a) {
	if ((*类型->m_Name).empty()) return;

	bool 多例 = a->count >= 多边形元素组->count;
	for (uint32 i = 0; i < 多边形元素组->count; ++i) {
		S_多边形* 多边形;

		if(!多边形元素组->ptr_userData[i]) continue;

		S_多边形元素& 多边形元素 = *多边形元素组->ptr_userData[i];
		if (多边形元素.count && 多边形元素.ptr_userData[0]) {
			多边形 = (S_多边形*)多边形元素.ptr_userData[0]->polygon;
		}
		else {
			continue;
		}
		

		switch (类型->m_分布方式) {
			case 0: {
				if (多边形->m_点自定义属性.find(*类型->m_Name) != 多边形->m_点自定义属性.end()) {

					auto& e = 多边形->m_点自定义属性[*类型->m_Name];
					if (!e) continue;
					//f_core_array_不对等复制(e, a);

					for (uint32 i = 0; i < 多边形元素.count; ++i) {
						auto* indexs = 多边形元素.ptr_userData[i]->vertIndex.data();
						uint32 faceVertNum = 多边形元素.ptr_userData[i]->vertIndex.size();

						//bool 多例 = a->count >= faceVertNum;
						for (uint32 k = 0; k < faceVertNum; ++k) {
							f_core_array_元素复制(e, a, indexs[k], 多例 ? i : 0);
						}
					}
				}
				break;
			}
			case 1: {
				if (多边形->m_面自定义属性.find(*类型->m_Name) != 多边形->m_面自定义属性.end()) {
					auto& e = 多边形->m_面自定义属性[*类型->m_Name];
					//f_core_array_不对等复制(e, a);

					for (uint32 k = 0; k < 多边形元素.count; ++k) {
						f_core_array_元素复制(e, a, 多边形元素.ptr_userData[k]->ID, 多例 ? i : 0);
					}
				}
				break;
			}
		}
	}
}

S_GPU内存块索引 f_surface_填充自定义属性(S_Mesh* me, S_Array* a, int32 分布方式) {
	S_GPU内存块索引 块;
	switch (分布方式)
	{
		case 0: {
			switch (f_core_array_getType(a)) {

				case E_值类型::e_Type_F32_1D: {
					块 = f_buf_alloc(S_Mesh::g_F32动态属性_点, 0);
					break;
				}
				case E_值类型::e_Type_I32_1D: {
					块 = f_buf_alloc(S_Mesh::g_I32动态属性_点, 0);
					break;
				}
				case E_值类型::e_Type_UI32_1D: {
					块 = f_buf_alloc(S_Mesh::g_UI32动态属性_点, 0);
					break;
				}
				case E_值类型::e_Type_Vec2_1D: {
					块 = f_buf_alloc(S_Mesh::g_Vec2动态属性_点, 0);
					break;
				}
				case E_值类型::e_Type_Vec3_1D: {
					块 = f_buf_alloc(S_Mesh::g_Vec3动态属性_点, 0);
					break;
				}
				case E_值类型::e_Type_Vec4_1D: {
					块 = f_buf_alloc(S_Mesh::g_Vec4动态属性_点, 0);
					break;
				}
				case E_值类型::e_Type_iVec4_1D: {
					块 = f_buf_alloc(S_Mesh::g_iVec4动态属性_点, 0);
					break;
				}
				default:
					break;
			}
			break;
		}
		case 1: {
			switch (f_core_array_getType(a)) {

				case E_值类型::e_Type_F32_1D: {
					块 = f_buf_alloc(S_Mesh::g_F32动态属性_面, 0);
					break;
				}
				case E_值类型::e_Type_I32_1D: {
					块 = f_buf_alloc(S_Mesh::g_I32动态属性_面, 0);
					break;
				}
				case E_值类型::e_Type_UI32_1D: {
					块 = f_buf_alloc(S_Mesh::g_UI32动态属性_面, 0);
					break;
				}
				case E_值类型::e_Type_Vec2_1D: {
					块 = f_buf_alloc(S_Mesh::g_Vec2动态属性_面, 0);
					break;
				}
				case E_值类型::e_Type_Vec3_1D: {
					块 = f_buf_alloc(S_Mesh::g_Vec3动态属性_面, 0);
					break;
				}
				case E_值类型::e_Type_Vec4_1D: {
					块 = f_buf_alloc(S_Mesh::g_Vec4动态属性_面, 0);
					break;
				}
				case E_值类型::e_Type_iVec4_1D: {
					块 = f_buf_alloc(S_Mesh::g_iVec4动态属性_面, 0);
					break;
				}
				default:
					break;
			}
			break;
		}
	}
	
	f_gbuf_fill(块, a->ptr_userData, 0, a->count);
	return 块;
}



void f_surface_多边形保存(FILE* f, const S_多边形* 多边形) {
	file_写入序列到文件(f, 多边形->m_顶点);
	file_写入序列到文件(f, 多边形->m_法线);
	file_写入序列到文件(f, 多边形->m_UV);
	file_写入序列到文件(f, 多边形->m_UV索引);
	

	uint32 num = 多边形->m_边.size();
	fwrite(&num, sizeof(uint32), 1, f);
	auto edge_ptr = 多边形->m_边.data();
	for (uint32 i = 0; i < num; ++i) {
		file_写入序列到文件(f, edge_ptr[i]->edge);
		edge_ptr[i]->edge;
	}

	num = 多边形->m_面.size();
	fwrite(&num, sizeof(uint32), 1, f);
	auto face_ptr = 多边形->m_面.data();
	for (uint32 i = 0; i < num; ++i) {
		file_写入序列到文件(f, face_ptr[i]->vertIndex);
		file_写入序列到文件(f, face_ptr[i]->uvLoopIndex);
		file_写入序列到文件(f, face_ptr[i]->edge);
		fwrite(&face_ptr[i]->材质槽, sizeof(uint32), 1, f);
	}
}

void f_surface_网格保存(FILE* f, const S_Mesh* me) {
	
}

S_多边形* f_surface_多边形加载(FILE* f) {
	S_多边形* poly = f_surface_创建多边形();

	file_读取序列到文件(f, &(poly->m_顶点));
	file_读取序列到文件(f, &(poly->m_法线));
	file_读取序列到文件(f, &(poly->m_UV));
	file_读取序列到文件(f, &(poly->m_UV索引));


	uint32 num = 0;
	fread(&num, sizeof(uint32), 1, f);
	for (uint32 i = 0; i < num; ++i) {
		S_边* 边 = new S_边;
		file_读取序列到文件(f, &(边->edge));
		poly->m_边.push_back(边);
	}

	fread(&num, sizeof(uint32), 1, f);
	for (uint32 i = 0; i < num; ++i) {
		S_面* 多边形面 = new S_面;
		多边形面->polygon = (S_结构对象指针)poly;

		file_读取序列到文件(f, &(多边形面->vertIndex));
		file_读取序列到文件(f, &(多边形面->uvLoopIndex));
		file_读取序列到文件(f, &(多边形面->edge));

		fread(&多边形面->材质槽, sizeof(uint32), 1, f);

		多边形面->ID = poly->m_面.size();
		poly->m_面.push_back(多边形面);
	}

	for (auto& e : poly->m_面自定义属性) {
		//f_core_array_resize(e.second, poly->m_面.size());
	}
	return poly;
}

S_多边形* f_surface_copy(const S_多边形* 多边形) {
	S_多边形* 新多边形 = f_surface_创建多边形();

	f_surface_copy(多边形, 新多边形);
	//新多边形->m_顶点 = 多边形->m_顶点;
	//新多边形->m_法线 = 多边形->m_法线;
	//新多边形->m_UV = 多边形->m_UV;
	//新多边形->m_UV索引 = 多边形->m_UV索引;
	//
	//
	//uint32 num = 多边形->m_边.size();
	//for (uint32 i = 0; i < num; ++i) {
	//	S_边* 边 = new S_边;
	//	边->edge = 多边形->m_边[i]->edge;
	//	新多边形->m_边.push_back(边);
	//}
	//
	//num = 多边形->m_面.size();
	//for (uint32 i = 0; i < num; ++i) {
	//	S_面* 多边形面 = new S_面;
	//	多边形面->polygon = (S_结构对象指针)多边形;
	//
	//	多边形面->vertIndex = 多边形->m_面[i]->vertIndex;
	//	多边形面->uvLoopIndex = 多边形->m_面[i]->uvLoopIndex;
	//	多边形面->edge = 多边形->m_面[i]->edge;
	//	多边形面->材质槽 = 多边形->m_面[i]->材质槽;
	//	新多边形->m_面.push_back(多边形面);
	//}
	return 新多边形;
}

void f_surface_copy(const S_多边形* 源多边形, S_多边形* 目标多边形) {
	目标多边形->m_顶点 = 源多边形->m_顶点;
	目标多边形->m_法线 = 源多边形->m_法线;
	目标多边形->m_UV = 源多边形->m_UV;
	目标多边形->m_UV索引 = 源多边形->m_UV索引;

	uint32 num = 源多边形->m_边.size();
	for (uint32 i = 0; i < num; ++i) {
		S_边* 边 = new S_边;
		边->edge = 源多边形->m_边[i]->edge;
		目标多边形->m_边.push_back(边);
	}


	num = 源多边形->m_面.size();
	for (uint32 i = 0; i < num; ++i) {
		S_面* 多边形面 = new S_面;
		多边形面->polygon = (S_结构对象指针)目标多边形;

		多边形面->vertIndex = 源多边形->m_面[i]->vertIndex;
		多边形面->uvLoopIndex = 源多边形->m_面[i]->uvLoopIndex;
		多边形面->edge = 源多边形->m_面[i]->edge;
		多边形面->材质槽 = 源多边形->m_面[i]->材质槽;
		多边形面->ID = 目标多边形->m_面.size();

		目标多边形->m_面.push_back(多边形面);
	}


	uint32 faceOffset = 0;
	num = 源多边形->m_元素组->count;

	f_core_array_resize((S_Array*)目标多边形->m_元素组, num);
	for (uint32 i = 0; i < num; ++i) {
		S_多边形元素* 元素 = 源多边形->m_元素组->ptr_userData[i];

		uint32 面数量 = 元素->count;
		S_多边形元素* 新元素 = (S_多边形元素*)f_core_array_new(面数量, sizeof(S_面*));
		for (uint32 j = 0; j < 面数量; ++j) {
			新元素->ptr_userData[j] = 目标多边形->m_面[faceOffset];
			++faceOffset;
		}

		目标多边形->m_元素组->ptr_userData[i] = 新元素;
	}

	for (auto& e : 目标多边形->m_面自定义属性) {
		f_core_array_resize(e.second, 目标多边形->m_面.size());
	}
}


void f_mesh_清除网格元素中相同索引(S_UI32Array2D* 网格元素) {
	for (uint32 i = 0; i < 网格元素->count; ++i) {
		
		S_UI32Array* 当前组 = 网格元素->ptr_userData[i];

		int32 num = 当前组->count;
		uint32* index = 当前组->ptr_userData;

		for (int32 j = 0; j < num; ++j) {
			if(index[j] == -1) continue;

			for (int32 k = j+1; k < num; ++k) {
				if (index[j] == index[k]) {
					index[k] = -1;
				}
			}
		}

		for (int32 j = 0; j < num; ) {
			if (当前组->ptr_userData[j] == -1) {
				f_core_array_erase((S_Array*)当前组, j);
				--num;
			}
			else {
				++j;
			}
		}
	}
}











